package com.lagou.filter;


import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import io.netty.buffer.ByteBufAllocator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.NettyDataBufferFactory;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * @ClassName AccessFilter
 * @Description TODO
 * @Author liqy
 * @Date 2019-3-5 13:58
 * @Version 1.0
 **/
public class AccessFilter implements GatewayFilter, Ordered {
    private final static Logger logger = LoggerFactory.getLogger(AccessFilter.class);
    //目标过滤器
    @Autowired
    private GatewayFilter delegate;


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest serverHttpRequest = exchange.getRequest();
        //判断需不需要校验token
        boolean notIntercept = this.noInterceptNosign(serverHttpRequest);
        logger.info("jieg={}", notIntercept);
        MultiValueMap<String, HttpCookie> cookies = serverHttpRequest.getCookies();
        System.out.println("cookies" + cookies);
        if (notIntercept) {
            return chain.filter(exchange);
        }
        if (CollectionUtils.isEmpty(cookies)) {
            return response(exchange.getResponse());
        }
        List<HttpCookie> token = cookies.get("token");
        if (CollectionUtils.isEmpty(token)) {
            return response(exchange.getResponse());
        }

        return chain.filter(exchange);
    }


    //处理post中 application/json


    private Mono<Void> result(ServerWebExchange exchange, ServerHttpRequest serverHttpRequest, String bodyStr, GatewayFilterChain chain) {
        //下面的将请求体再次封装写回到request里，传到下一级，否则，由于请求体已被消费，后续的服务将取不到值
       /* URI uri = serverHttpRequest.getURI();
        ServerHttpRequest request = serverHttpRequest.mutate().uri(uri).build();
        DataBuffer bodyDataBuffer = stringBuffer(bodyStr);
        Flux<DataBuffer> bodyFlux = Flux.just(bodyDataBuffer);
        request = new ServerHttpRequestDecorator(request) {
            @Override
            public Flux<DataBuffer> getBody() {
                return bodyFlux;
            }
        };*/
        //封装request，传给下一级
        //  return chain.filter(exchange.mutate().request(request).build());
        return chain.filter(exchange);

    }

    private boolean noInterceptNosign(ServerHttpRequest serverHttpRequest) {
        URI uri = serverHttpRequest.getURI();
        String path = uri.getPath();
        logger.info("判断需不需要过滤{}path =" + path);
        String[] ac = org.springframework.util.StringUtils.split(path.substring(1), "/");
        String serverName = ac[0];//服务的总路径
        String methdUrl = ac[1];
        //服务分两种加服务标识和不加服务标识 TODO
        if (path.contains("login") || path.contains("register") ||
                path.contains("email")
                || path.contains("create")) {
            return true;
        }
        return false;
    }


    //处理放开的路径
    private boolean notIntercept(ServerHttpRequest serverHttpRequest) {
        URI uri = serverHttpRequest.getURI();
        String path = uri.getPath();
        logger.info("判断需不需要过滤{}path =" + path);
        String[] ac = org.springframework.util.StringUtils.split(path.substring(1), "/");
        String serverName = ac[0];//服务的总路径
        String methdUrl = ac[1];

        return false;
    }

    //1为postJson  2为postForm


    private Mono<Void> response(ServerHttpResponse response) {
        return responseResult(response);
    }

    //处理返回数据
    private Mono<Void> responseResult(ServerHttpResponse response) {


        response.setStatusCode(HttpStatus.FORBIDDEN);

        return response.setComplete();
    }


    @Override
    public int getOrder() {
        return -1;
    }


    /**
     * 获取请求体中的字符串内容
     *
     * @param serverHttpRequest
     * @return
     */
    private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) {

        Flux<DataBuffer> body = serverHttpRequest.getBody();
        StringBuilder sb = new StringBuilder();
        body.subscribe(buffer -> {
            List<String> list = Lists.newArrayList();
            byte[] bytes = new byte[buffer.readableByteCount()];
            buffer.read(bytes);
            DataBufferUtils.release(buffer);
            String bodyString = new String(bytes, StandardCharsets.UTF_8);
            sb.append(bodyString);
        });
        return sb.toString();
    }

    private DataBuffer stringBuffer(String value) {
        DataBuffer buffer = null;
        byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
        NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
        buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
        buffer.write(bytes);
        return buffer;

    }

    //将name=''&value=''转换成map
    private JSONObject getJson(String param) {
        String nvStrArr[] = param.split("&");

        JSONObject map = new JSONObject();

        for (String nvStr : nvStrArr) {
            map.put(nvStr.substring(0, nvStr.indexOf("=")), nvStr.substring(nvStr.indexOf("=") + 1));
        }
        return map;
    }
}
